home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
fwcp
/
src
/
key.c
< prev
next >
Wrap
Text File
|
1995-03-14
|
14KB
|
625 lines
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <jctype.h>
#include <string.h>
#include <malloc.h>
#include <dos.h>
#include "defs.h"
#include "key.h"
#define KEY_BUF_SIZ 256
#define KEY_BUF_MSK 255
static char matrix[16];
static int key_len=0;
static int key_top=0;
static int key_pos=0;
static struct {
int ch;
int ec;
} key_buf[KEY_BUF_SIZ];
static struct {
int mask;
int ec;
int ch;
} assign[]={
{ 0xFF00, 0x4800, 0x8000 }, /* 挿入 */
{ 0xFF00, 0x4B00, 0x007F }, /* 削除 */
{ 0xFF04, 0x4E00, 0x000B }, /* HOME */
{ 0xFF04, 0x4E04, 0x000C }, /* CLS */
{ 0xFF00, 0x7300, 0x000D }, /* 実行 */
{ 0xFF00, 0x7200, 0x001B }, /* 取消 */
{ 0xFF00, 0x5D00, 0x8001 }, /* PF1 */
{ 0xFF00, 0x5E00, 0x8002 }, /* PF2 */
{ 0xFF00, 0x5F00, 0x8003 }, /* PF3 */
{ 0xFF00, 0x6000, 0x8004 }, /* PF4 */
{ 0xFF00, 0x6100, 0x8005 }, /* PF5 */
{ 0xFF00, 0x6200, 0x8006 }, /* PF6 */
{ 0xFF00, 0x6300, 0x8007 }, /* PF7 */
{ 0xFF00, 0x6400, 0x8008 }, /* PF8 */
{ 0xFF00, 0x6500, 0x8009 }, /* PF9 */
{ 0xFF00, 0x6600, 0x800A }, /* PF10 */
{ 0xFF00, 0x6900, 0x800B }, /* PF11 */
{ 0xFF00, 0x5B00, 0x800C }, /* PF12 */
{ 0xFF00, 0x7400, 0x800D }, /* PF13 */
{ 0xFF00, 0x7500, 0x800E }, /* PF14 */
{ 0xFF00, 0x7600, 0x800F }, /* PF15 */
{ 0xFF00, 0x7700, 0x8010 }, /* PF16 */
{ 0xFF00, 0x7800, 0x8011 }, /* PF17 */
{ 0xFF00, 0x7900, 0x8012 }, /* PF18 */
{ 0xFF00, 0x7A00, 0x8013 }, /* PF19 */
{ 0xFF00, 0x7B00, 0x8014 }, /* PF20 */
{ 0xFF10, 0x4D10, 0x8017 }, /* ^UP */
{ 0xFF10, 0x5010, 0x8018 }, /* ^DOWN */
{ 0xFF10, 0x4F10, 0x8019 }, /* ^LEFT */
{ 0xFF10, 0x5110, 0x801A }, /* ^RIGHT*/
{ 0x0000, 0x0000, 0x0000 },
};
static int KYB_read(int sw,int *ec)
{
union REGS regs;
regs.h.ah = 0x09;
regs.h.al = sw;
int86(0x90,®s,®s);
*ec = regs.x.bx;
return regs.x.dx;
}
static int KYB_inpchk(int *ch,int *ec)
{
union REGS regs;
regs.h.ah = 0x07;
int86(0x90,®s,®s);
*ec = regs.x.bx;
*ch = regs.x.dx;
return regs.h.al;
}
static int KYB_matrix(char *tmp)
{
union REGS regs;
struct SREGS seg;
union {
char far *p;
short s[2];
} pp;
pp.p = (char far *)(tmp);
regs.h.ah = 0x0A;
regs.x.di = pp.s[0];
seg.ds = pp.s[1];
int86x(0x90, ®s, ®s, &seg);
return regs.h.ah;
}
static void NEW_bufset(int ch,int ec)
{
if ( key_len >= KEY_BUF_SIZ )
return;
key_buf[key_top].ch = ch;
key_buf[key_top].ec = ec;
key_top++;
key_top &= KEY_BUF_MSK;
key_len++;
}
static int NEW_inpchk(int *ch,int *ec)
{
int i, n;
int ch2, ec2;
static struct {
int on;
int ec;
int st;
} ext_tab[] = {
{ 0x8015, 0x7D00, FALSE }, /* COPY */
{ 0x8016, 0x7C00, FALSE }, /* BREAK */
{ 0x0000, 0x0000, 0 },
};
KYB_matrix(matrix);
for ( i = 0 ; (n = ext_tab[i].ec >> 8) != 0 ; i++ ) {
if ( (matrix[n / 8] & (1 << (n % 8))) != 0 ) {
if ( ext_tab[i].st == FALSE )
NEW_bufset(ext_tab[i].on, ext_tab[i].ec);
ext_tab[i].st = TRUE;
} else
ext_tab[i].st = FALSE;
}
if ( key_len > 0 ) {
*ch = key_buf[key_pos].ch;
*ec = key_buf[key_pos].ec;
return key_len;
}
*ch = KYB_read(1, ec);
if ( (*ec & 0xFF00) == 0xFF00 )
return 0;
for ( i = 0 ; assign[i].ec != 0 ; i++ ) {
if ( (*ec & assign[i].mask) == assign[i].ec ) {
while ( KYB_inpchk(&ch2, &ec2) > 0 && *ch != ch2 && *ec == ec2 )
ch2 = KYB_read(0, &ec2);
*ch = assign[i].ch;
NEW_bufset(assign[i].ch, *ec);
return key_len;
}
}
NEW_bufset(*ch, *ec);
return key_len;
}
static int NEW_read(int sw, int *ec)
{
int ch=0xFFFF;
do {
if ( NEW_inpchk(&ch,ec) > 0 ) {
key_pos++;
key_pos &= KEY_BUF_MSK;
key_len--;
break;
}
} while ( sw == 0 );
return ch;
}
int isank(ch)
int ch;
{
return ( !iskanji(ch) && ch >= ' ' && ch != 0x7F );
}
void tsleep(tic)
int tic;
{
union REGS regs;
regs.x.cx = tic * 100;
int86(0xFD,®s,®s);
}
/**********************
^A=LEFT_CUR
^B=RIGHT_CUR
^C=LEFT_NODE
^D=RIGHT_NODE
PF1=
RIGHT="any strings"
***********************/
static int any_ent = 0;
static int any_max = 0;
static char **any_vct;
static char *any_str = NULL;
static struct {
int code;
char *key;
} key_name[] = {
{ 0x8000, "INS" },
{ 0x8001, "PF1" },
{ 0x8002, "PF2" },
{ 0x8003, "PF3" },
{ 0x8004, "PF4" },
{ 0x8005, "PF5" },
{ 0x8006, "PF6" },
{ 0x8007, "PF7" },
{ 0x8008, "PF8" },
{ 0x8009, "PF9" },
{ 0x800A, "PF10" },
{ 0x800B, "PF11" },
{ 0x800C, "PF12" },
{ 0x800D, "PF13" },
{ 0x800E, "PF14" },
{ 0x800F, "PF15" },
{ 0x8010, "PF16" },
{ 0x8011, "PF17" },
{ 0x8012, "PF18" },
{ 0x8013, "PF19" },
{ 0x8014, "PF20" },
{ 0x8015, "COPY" },
{ 0x8016, "BREAK" },
{ 0x8017, "^UP" },
{ 0x8018, "^DOWN" },
{ 0x8019, "^LEFT" },
{ 0x801A, "^RIGHT" },
{ 0x001B, "ESC" },
{ 0x001C, "LEFT" },
{ 0x001D, "RIGHT" },
{ 0x001E, "UP" },
{ 0x001F, "DOWN" },
{ 0x007F, "DEL" },
{ 0x0000, NULL }
};
static struct {
int code;
char *str;
} key_man[] = {
/* 12345678901234567890 */
{ K_END_OF, "End of Program" },
{ K_BACK_SPC, "Edit back space" },
{ K_DEL_CHAR, "Edit delete char" },
{ K_LEFT_CUR, "Edit left cursol" },
{ K_RIGHT_CUR, "Edit right cursol" },
{ K_CUT_BUFF, "Edit cut line" },
{ K_DEL_LINE, "Edit delete line" },
{ K_UNDO_LINE, "Edit paste line" },
{ K_HIS_LINE, "Edit undo char" },
{ K_END_LINE, "Edit execute" },
{ K_WIND_CNG, "Wind change" },
{ K_UP_NODE, "Wind up cursol" },
{ K_DOWN_NODE, "Wind down cursol" },
{ K_GETS_WIND, "Edit get act wind" },
{ K_GETS_SRC, "Edit get src wind" },
{ K_GETS_DIS, "Edit get dis wind" },
{ K_COPY_WIND, "Copy src to dis" },
{ K_DIR_MENU, "Wind chdir menu" },
{ K_SCREEN_FLUSH,"Screen flush" },
{ K_MARK_FILE, "Wind mark file" },
{ K_INIT_WIND, "Wind init" },
{ K_MARK_ALL, "Wind mark all file" },
{ K_SKIP_DOC, "Wind skip doc file" },
{ K_ABORT, "Abort" },
{ K_CONSOLE, "DOS Console" },
{ K_HISTORY, "Edit history" },
{ K_HIS_DIR, "Wind chdir history" },
{ K_TREE_DIR, "Wind chdir tree" },
{ K_SORT_MODE, "Wind disp sort mode" },
{ K_HELP, "Help screen" },
{ K_DRV_MENU, "Wind Drive menu" },
{ K_UP_MARK, "Wind mark up node" },
{ K_DOWN_MARK, "Wind mark down node" },
{ 0, NULL },
};
static struct {
int code;
char *str;
} func_name[] = {
{ K_END_OF, "END_OF" },
{ K_BACK_SPC, "BACK_SPC" },
{ K_DEL_CHAR, "DEL_CHAR" },
{ K_LEFT_CUR, "LEFT_CUR" },
{ K_RIGHT_CUR, "RIGHT_CUR" },
{ K_CUT_BUFF, "CUT_BUFF" },
{ K_DEL_LINE, "DEL_LINE" },
{ K_UNDO_LINE, "UNDO_LINE" },
{ K_HIS_LINE, "HIS_LINE" },
{ K_END_LINE, "END_LINE" },
{ K_WIND_CNG, "WIND_CNG" },
{ K_UP_NODE, "UP_NODE" },
{ K_DOWN_NODE, "DOWN_NODE" },
{ K_GETS_WIND, "GETS_WIND" },
{ K_GETS_SRC, "GETS_SRC" },
{ K_GETS_DIS, "GETS_DIS" },
{ K_COPY_WIND, "COPY_WIND" },
{ K_DIR_MENU, "DIR_MENU" },
{ K_SCREEN_FLUSH,"SCREEN_FLUSH" },
{ K_MARK_FILE, "MARK_FILE" },
{ K_INIT_WIND, "INIT_WIND" },
{ K_MARK_ALL, "MARK_ALL" },
{ K_SKIP_DOC, "SKIP_DOC" },
{ K_ABORT, "ABORT" },
{ K_CONSOLE, "CONSOLE" },
{ K_HISTORY, "HISTORY" },
{ K_HIS_DIR, "HIS_DIR" },
{ K_TREE_DIR, "TREE_DIR" },
{ K_SORT_MODE, "SORT_MODE" },
{ K_HELP, "HELP" },
{ K_DRV_MENU, "DRV_MENU" },
{ K_UP_MARK, "UP_MARK" },
{ K_DOWN_MARK, "DOWN_MARK" },
{ 0x0000, NULL }
};
#define CTRL_MAP_LEN 33
static int ctrl_map[] = {
K_CONSOLE, /* ^@ */
K_HIS_LINE, /* ^A */
K_CUT_BUFF, /* ^B */
K_INIT_WIND, /* ^C */
K_GETS_DIS, /* ^D */
EOF, /* ^E */
EOF, /* ^F */
EOF, /* ^G */
K_BACK_SPC, /* ^H */
K_WIND_CNG, /* ^I */
EOF, /* ^J */
EOF, /* ^K */
K_SCREEN_FLUSH, /* ^L */
K_END_LINE, /* ^M */
K_SKIP_DOC, /* ^N */
EOF, /* ^O */
K_HISTORY, /* ^P */
K_MARK_FILE, /* ^Q */
K_SORT_MODE, /* ^R */
K_GETS_SRC, /* ^S */
EOF, /* ^T */
K_UNDO_LINE, /* ^U */
K_HELP, /* ^V */
K_MARK_ALL, /* ^W */
K_DEL_LINE, /* ^X */
K_DEL_LINE, /* ^Y */
K_GETS_WIND, /* ^Z */
K_ABORT, /* ESC */
K_LEFT_CUR, /* LEFT */
K_RIGHT_CUR, /* RIGHT */
K_UP_NODE, /* UP */
K_DOWN_NODE, /* DOWN */
K_DEL_CHAR, /* DEL */
};
#define PF_MAP_LEN 27
static int pf_map[] = {
EOF, /* INS */
K_COPY_WIND, /* PF1 */
K_HIS_DIR, /* PF2 */
K_DIR_MENU, /* PF3 */
K_TREE_DIR, /* PF4 */
K_DRV_MENU, /* PF5 */
K_MARK_FILE, /* PF6 */
K_MARK_ALL, /* PF7 */
K_SKIP_DOC, /* PF8 */
K_CONSOLE, /* PF9 */
K_END_OF, /* PF10 */
EOF, /* PF11 */
EOF, /* PF12 */
EOF, /* PF13 */
EOF, /* PF14 */
EOF, /* PF15 */
EOF, /* PF16 */
EOF, /* PF17 */
EOF, /* PF18 */
EOF, /* PF19 */
EOF, /* PF20 */
K_COPY_WIND, /* COPY */
K_ABORT, /* BREAK*/
EOF, /* ^UP */
EOF, /* ^DOWN */
EOF, /* ^LEFT */
EOF, /* ^RIGHT*/
};
static char *strany(char *str)
{
int n = 0;
int c, i;
static char tmp[LINSIZ + 2];
while ( n < LINSIZ && *str != '\0' ) {
if ( iskan(str) ) {
tmp[n++] = *(str++);
tmp[n++] = *(str++);
} else if ( *str == '\\' ) {
str++;
switch(*(str++)) {
case 'r':
case 'n': tmp[n++] = '\r'; break;
case 'b': tmp[n++] = '\b'; break;
case 'f': tmp[n++] = '\f'; break;
case 't': tmp[n++] = '\t'; break;
case 'x':
for ( i = c = 0 ; i < 2 && isxdigit(*str) ; i++ ) {
if ( isdigit(*str) )
c = c * 16 + (*(str++) - '0');
else {
c = c * 16 + (toupper(*str) - 'A' + 10);
str++;
}
}
tmp[n++] = c;
break;
default:
if ( *str >= '0' && *str <= '7' ) {
for ( i = c = 0 ; i < 3 &&
*str >= '0' && *str <= '7' ; i++ )
c = c * 8 + (*(str++) - '0');
tmp[n++] = c;
} else
tmp[n++] = *(str - 1);
break;
}
} else {
tmp[n++] = *(str++);
}
}
tmp[n] = '\0';
return tmp;
}
static int enc_key(char *str)
{
int n;
for ( n = 0 ; key_name[n].key != NULL ; n++ ) {
if ( strcmp(str, key_name[n].key) == 0 )
return key_name[n].code;
}
if ( *str == '^' )
return toupper((str[1]) - '@');
else if ( strncmp(str, "CTRL+", 5) == 0 )
return toupper((str[5]) - '@');
return EOF;
}
static int enc_func(char *str)
{
int n;
char *p;
for ( n = 0 ; func_name[n].str != NULL ; n++ ) {
if ( strcmp(str, func_name[n].str) == 0 )
return func_name[n].code;
}
if ( *(str++) == '"' ) {
if ( (p = strrchr(str, '"')) != NULL )
*p = '\0';
if ( any_ent >= any_max ) {
any_max += 8;
if ( any_vct == (char **)NULL )
any_vct = (char **)malloc(sizeof(char *) * any_max);
else
any_vct = (char **)realloc(any_vct, sizeof(char *) * any_max);
if ( any_vct == (char **)NULL ) {
fprintf(stderr, "key strings malloc error\n");
exit(1);
}
any_vct[any_ent] = strdup(str);
}
return (K_STRING + (any_ent++));
}
return EOF;
}
static char *key_str(int code)
{
int n;
static char tmp[8];
for ( n = 0 ; key_name[n].key != NULL ; n++ ) {
if ( code == key_name[n].code )
return key_name[n].key;
}
sprintf(tmp, "^%c", code + '@');
return tmp;
}
static char *key_cmd(int code)
{
int n;
for ( n = 0 ; key_man[n].str != NULL ; n++ ) {
if ( code == key_man[n].code )
return key_man[n].str;
}
if ( code >= K_STRING )
return any_vct[code - K_STRING];
return "";
}
void key_map()
{
int n, c;
int x = 0, y = 2;
for ( n = 0 ; n < CTRL_MAP_LEN ; n++ ) { /* ctrl_map */
c = (n == 32 ? 0x7F : n);
LOCATE(x, y);
FPUTS("%-5s %-20.20s", key_str(c), key_cmd(ctrl_map[n]));
if ( ++y > (SCR_Y - 2) ) {
y = 2;
x += 26;
}
}
for ( n = 0 ; n < PF_MAP_LEN ; n++ ) { /* pf_map */
c = 0x8000 | n;
LOCATE(x, y);
FPUTS("%-5s %-20.20s", key_str(c), key_cmd(pf_map[n]));
if ( ++y > (SCR_Y - 2) ) {
y = 2;
x += 26;
}
}
}
int REALCH()
{
int ec;
if ( any_str != NULL ) {
if ( *any_str != '\0' )
return (*(any_str++) & 0x00FF);
any_str = NULL;
}
return NEW_read(0, &ec);
}
int GETCH()
{
int ch;
LOOP:
do {
ch = REALCH();
if ( (ch & 0xFF00) != 0 ) {
if ( (ch & 0xFF00) == 0x8000 && (ch & 0x00FF) < PF_MAP_LEN )
ch = pf_map[ch & 0x00FF];
else
ch = EOF;
} else if ( ch < ' ' )
ch = ctrl_map[ch];
else if ( ch == 0x007F )
ch = ctrl_map[32];
} while ( ch == EOF );
if ( ch >= K_STRING ) {
any_str = strany(any_vct[ch - K_STRING]);
goto LOOP;
}
return ch;
}
void UNGETCH(int ch)
{
if ( any_str != NULL )
any_str--;
else
NEW_bufset(ch, 0);
}
int KBHIT()
{
int ch,ec;
if ( any_str != NULL && *any_str != '\0' )
return 1;
else
return NEW_inpchk(&ch, &ec);
}
void key_defs(FILE *fp, char *tmp)
{
int ch;
char *p;
while ( fgets(tmp, LINSIZ, fp) != NULL ) {
if ( (p = strchr(tmp, '\n')) != NULL )
*p = '\0';
if ( strcmp(tmp, "#end") == 0 )
break;
if ( (p = strchr(tmp, '=')) == NULL )
continue;
*(p++) = '\0';
while ( isspace(*p) )
p++;
if ( (ch = enc_key(tmp)) == EOF )
continue;
if ( (ch & 0xFF00) == 0 && ch < ' ' )
ctrl_map[ch] = enc_func(p);
else if ( ch == 0x007F )
ctrl_map[32] = enc_func(p);
else if ( (ch & 0x00FF) < PF_MAP_LEN )
pf_map[ch & 0x00FF] = enc_func(p);
}
}
void KEYINIT()
{
}
void KEYEND()
{
}
void setkey()
{
}